package com.cm.sys.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.cm.sys.framework.application.ApiResponseCode;
import com.cm.sys.framework.execption.BusinessException;
import com.cm.sys.framework.utils.DateUtil;
import com.cm.sys.system.dao.BusinessInfoMapper;
import com.cm.sys.system.dao.MenuMapper;
import com.cm.sys.system.dao.MenuRelationMapper;
import com.cm.sys.system.dao.RoleAuthMapper;
import com.cm.sys.system.entity.Menu;
import com.cm.sys.system.entity.MenuRelation;
import com.cm.sys.system.service.MenuService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @ClassNameMenuServiceImpl
 * @Description
 * @Author WZC
 * @Date2019/11/30 6:23
 * @Version V1.0
 **/
@Service
public class MenuServiceImpl implements MenuService {
    private static final Logger logger = LoggerFactory.getLogger(MenuService.class);
    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RoleAuthMapper roleAuthMapper;

    @Autowired
    private BusinessInfoMapper businessInfoMapper;

    @Autowired
    private MenuRelationMapper relationMapper;

    @Value("${BusinessMenu}")
    private String BusinessMenu;

    @Value("${FuncMenu}")
    private String FuncMenu;

    /**
     * 保存菜单
     *
     * @param menu
     * @return menu
     */
    @Override
    public Menu saveMenu(Menu menu) {
        Integer id = null;
        //排除路由相同的
        id = menuMapper.selectRoute(menu.getRoute());
        if (id != null) {
            throw new BusinessException(ApiResponseCode.MENUROTE_ERROR.getCode(), ApiResponseCode.MENUROTE_ERROR.getMessage());
        }
        //剔除重复菜单名id
        Integer parentName = menuMapper.selectParentName(menu.getParentName());
        if (parentName != null) {
            throw new BusinessException(ApiResponseCode.MENUPARENTNAME_EOOR.getCode(), ApiResponseCode.MENUPARENTNAME_EOOR.getMessage());
        }
        menu.setCreateTime(DateUtil.getTimestamp());
        menu.setUpdateTime(DateUtil.getTimestamp());
        Integer count = menuMapper.insert(menu);
        logger.info("本级菜单保存出参===============添加之后========【{}】===============", count);
        return menu;
    }

    /**
     * 修改菜单
     *
     * @param menu
     * @return
     */
    @Override
    public Menu updateMenu(Menu menu) {
        //查询出所有数据
        List<Menu> menus = menuMapper.selectAll();
        
        for (Menu m : menus) {
        	//根据ID判断出需要修改的那一条数据
            if(m.getId().equals(menu.getId())){
            	//不允许将根菜单改为子菜单
            	if (m.getParentId().equals(0) && !menu.getParentId().equals(0)) {
            		throw new BusinessException(ApiResponseCode.MENUPARETNORSUNID_ERROR.getCode(), ApiResponseCode.MENUPARETNORSUNID_ERROR.getMessage());
            	}
            //判断修改的那一条数据与其他的数据是否有重复菜单名或路由
            }else {
            	if(m.getParentName().equalsIgnoreCase(menu.getParentName())){
            		throw new BusinessException(ApiResponseCode.MENUPARENTNAME_EOOR.getCode(), ApiResponseCode.MENUPARENTNAME_EOOR.getMessage());
            	}
            	if(m.getRoute().equalsIgnoreCase(menu.getRoute())){
            		throw new BusinessException(ApiResponseCode.MENUROTE_ERROR.getCode(), ApiResponseCode.MENUROTE_ERROR.getMessage());
            	}
            }
        }
        menu.setUpdateTime(DateUtil.getTimestamp());
        Integer count = menuMapper.updateMenu(menu);
        logger.info("用户对象更新的出参==================【{}】===============", count);
        return menu;
    }

    /**
     * 删除菜单
     *
     * @param menuId
     * @return
     */
    @Override
    public int deleteMenu(Integer menuId) {
        Integer count = null;
        Menu menu = menuMapper.selectMenu(menuId);
        if (StringUtils.isEmpty(menu)) {
            throw new BusinessException(ApiResponseCode.CODE_LOGIN.getCode(), "路由错误缺少id");
        }
        logger.info("菜单删除的入参==================【{}】===============", menuId);
        List<Menu> allMenu = menuMapper.selectAll();
        if (allMenu.isEmpty()) {
            throw new BusinessException(ApiResponseCode.MENULIST_ERROR.getCode(), ApiResponseCode.MENULIST_ERROR.getMessage());
        }
        //该菜单下有菜单不允许删除
        for (Menu menus : allMenu) {
            if (menuId.equals(menus.getParentId())) {
                throw new BusinessException(ApiResponseCode.MENUPARETN_ERROR.getCode(), ApiResponseCode.MENUPARETN_ERROR.getMessage());
            }
        }
        count = menuMapper.deleteByPrimaryKey(menuId);
        int i = roleAuthMapper.deleteByMenuId(menuId);
        logger.info("菜单删除的出参==================【{}】===============", count);
        if (count != 1) {
            throw new BusinessException(ApiResponseCode.DEL_FAIL.getCode(), ApiResponseCode.DEL_FAIL.getMessage());
        }
        return count;
    }

    /**
     * 查询菜单
     * @param
     * @return
     */
    @Override
    public Map<String, Object> selectMenus() {
        Map<String, Object> map = new HashMap<>();
        //所有菜单
        List<Menu> allMenu = menuMapper.selectAll();
        if (!CollectionUtils.isEmpty(allMenu)) {
            Collections.sort(allMenu, new Comparator<Menu>() {
                @Override
                public int compare(Menu arg0, Menu arg1) {
                    //第一次比较ParentId
                    int sortInt1 = arg0.getParentId().compareTo(arg1.getParentId());
                    if (sortInt1 == 0) {
                        //第二次比较SortInt
                        int sortInt2 = arg0.getSortInt().compareTo(arg1.getSortInt());
                        return sortInt2;
                    }
                    return sortInt1;
                }
            });
        } else {
            throw new BusinessException(ApiResponseCode.MENULIST_ERROR.getCode(), ApiResponseCode.MENULIST_ERROR.getMessage());
        }
        //创建根目录菜单集合
        ArrayList<Menu> listMenu = new ArrayList<>();
        //筛选根目录菜单
        if (!CollectionUtils.isEmpty(allMenu)) {
            for (Menu menu : allMenu) {
                if (menu.getParentId() == 0) {
                    listMenu.add(menu);
                }
            }
        }
        //将子级菜单放到根目录下
        if (!CollectionUtils.isEmpty(listMenu)) {
            for (Menu menu : listMenu) {
                Integer id = menu.getId();
                //筛选所有子级菜单
                List<Menu> listChild = getChild(id, allMenu);
                if (!CollectionUtils.isEmpty(listChild)) {
                    menu.setChildrens(listChild);
                }
            }
        }
        map.put("menu", listMenu);
        logger.info("菜单列表查询的出参==================【{}】===============", JSON.toJSON(listMenu));
        return map;
    }

    /**
     * 子菜单集合
     * @param id
     * @param allMenu
     * @return
     */
    private List<Menu> getChild(Integer id, List<Menu> allMenu) {
        //创建子级菜单集合
        List<Menu> listChild = new ArrayList<>();//SIZE=2
        for (Menu menu : allMenu) {
            Integer parentId = menu.getParentId();
            if (parentId.equals(id)) {
                listChild.add(menu);
            }
        }
        //递归
        for (Menu menu : listChild) {
            menu.setChildrens(getChild(menu.getId(),allMenu));
            if (listChild.size() == 0) {
                return null;
            }
        }
        return listChild;
    }

    /**
     * 活动菜单
     *
     * @param roleId
     * @return
     */
    @Override
    public Map<String, Object> activityTypeMenu(Integer roleId) {
        //通过 角色 id 获得 菜单id
        List<Integer> menuIds = roleAuthMapper.selectByRoleMenu(roleId);
        if (CollectionUtils.isEmpty(menuIds)) {
            throw new BusinessException(ApiResponseCode.MUNEINSERTTOID_EOOR.getCode(), ApiResponseCode.MUNEINSERTTOID_EOOR.getMessage());
        }
        //返回菜单集合
        List<Menu> activityTypeMenus = menuMapper.selectMenus(menuIds);
        logger.info("<===============返回的菜单集合==【{}】====>",activityTypeMenus);
        
        if (!CollectionUtils.isEmpty(activityTypeMenus)) {
            Collections.sort(activityTypeMenus, new Comparator<Menu>() {
                @Override
                public int compare(Menu arg0, Menu arg1) {
                    //第一次比较ParentId
                    int sortInt1 = arg0.getParentId().compareTo(arg1.getParentId());
                    //如果专业相同则进行第二次比较
                    if (sortInt1 == 0) {
                        //第二次比较SortInt
                        int sortInt2 = arg0.getSortInt().compareTo(arg1.getSortInt());
                        return sortInt2;
                    }
                    return sortInt1;
                }
            });
        } else {
            throw new BusinessException(ApiResponseCode.MENULIST_ERROR.getCode(), ApiResponseCode.MENULIST_ERROR.getMessage());
        }

        //创建根目录菜单集合
        List<Menu> listMenu = new ArrayList<>();
        List<MenuRelation> relations = relationMapper.selectAll();

        //筛选根目录菜单
        if (!CollectionUtils.isEmpty(activityTypeMenus)) {
            for (Menu menu : activityTypeMenus) {
                if (menu.getParentId() == 0) {
                    listMenu.add(menu);
                }
            }
        }
        //创建业务线根目录
        Menu business = null;
        Menu func = null;
        //创建系统设置根目录
        //遍历关系菜单，找出日志查看跟菜单和功能菜单根菜单的菜单对象
        MenuRelation mr = null;         //  日志查看根菜单
        MenuRelation fr = null;         //  功能根菜单
        for (MenuRelation relation : relations) {
            if(relation.getFunction().equals(BusinessMenu)){
                mr = relation;
            }
            if(relation.getFunction().equals(FuncMenu)){
                fr = relation;
            }
        }
        //将子级菜单放到根目录下
        if (!CollectionUtils.isEmpty(listMenu)) {
            for (Menu menu : listMenu) {
                Integer id = menu.getId();
                //筛选所有子级菜单
                List<Menu> listChild = getChild(id,activityTypeMenus);
                if (!CollectionUtils.isEmpty(listChild)) {
                    menu.setChildrens(listChild);
                }
            }
        }
        //根据菜单关系对象的id找到对应的根菜单对象
        for (Menu menu : listMenu) {
            if(mr!=null&&menu.getId().equals(mr.getMenuId())){
                business = menu;
            }
            if(fr != null && menu.getId().equals(fr.getMenuId())){
                func = menu;
            }
        }
        //遍历赋值完成后，为每个业务线放入功能菜单子集
        if(business!=null&&func!=null){
            for (Menu menu1 : business.getChildrens()) {
                menu1.setChildrens(func.getChildrens());
            }
            listMenu.add(business);
            listMenu.remove(func);
        }else{
            throw new BusinessException(ApiResponseCode.ERROR.getCode(),"请填补数据库功能菜单以及日志查看菜单缺省值");
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("activityTypeMenus", listMenu);
        logger.info("菜单列表查询的出参==================【{}】===============", JSON.toJSON(listMenu));
        return map;
    }

    @Override
    public Menu selectMenu(Integer menuId) {
        Menu menu =  menuMapper.selectMenu(menuId);
        return menu;
    }


    @Override
    public Menu updaterStatus(Menu menu) {
        menuMapper.updateMenu(menu);
        Integer id = menu.getId();
        Integer reviewStatus = menu.getReviewStatus();
        Map map = new HashMap();
        map.put("approvalStatus",reviewStatus);
        map.put("menuId",id);
        businessInfoMapper.updateStatus(map);
        logger.info("修改菜单功能的出参==================【{}】===============",JSON.toJSON(menu));
        return menu;
        
    }

    @Override
    public Map<String, Object> activityTypeMenuGroup(Integer userId) {

        List<Menu> activityTypeMenus = menuMapper.selectActivityMenus(userId);
        logger.info("<===============返回的菜单集合==【{}】====>",activityTypeMenus);
        
        if (!CollectionUtils.isEmpty(activityTypeMenus)) {
            Collections.sort(activityTypeMenus, new Comparator<Menu>() {
                @Override
                public int compare(Menu arg0, Menu arg1) {
                    //第一次比较ParentId
                    int sortInt1 = arg0.getParentId().compareTo(arg1.getParentId());
                    //如果专业相同则进行第二次比较
                    if (sortInt1 == 0) {
                        //第二次比较SortInt
                        int sortInt2 = arg0.getSortInt().compareTo(arg1.getSortInt());
                        return sortInt2;
                    }
                    return sortInt1;
                }
            });
        } else {
            throw new BusinessException(ApiResponseCode.MENULIST_ERROR.getCode(), ApiResponseCode.MENULIST_ERROR.getMessage());
        }
        //创建根目录菜单集合
        List<Menu> listMenu = new ArrayList<>();
        List<MenuRelation> relations = relationMapper.selectAll();
        //筛选根目录菜单
        if (!CollectionUtils.isEmpty(activityTypeMenus)) {
            for (Menu menu : activityTypeMenus) {
                if (menu.getParentId() == 0) {
                    listMenu.add(menu);
                }
            }
        }
        //创建业务线根目录
        Menu business = null;
        Menu func = null;
        //创建系统设置根目录
        //遍历关系菜单，找出日志查看跟菜单和功能菜单根菜单的菜单对象
        MenuRelation mr = null;         //  日志查看根菜单
        MenuRelation fr = null;         //  功能根菜单
        for (MenuRelation relation : relations) {
            if(relation.getFunction().equals(BusinessMenu)){
                mr = relation;
            }
            if(relation.getFunction().equals(FuncMenu)){
                fr = relation;
            }
        }
        //将子级菜单放到根目录下
        if (!CollectionUtils.isEmpty(listMenu)) {
            for (Menu menu : listMenu) {
                Integer id = menu.getId();
                //筛选所有子级菜单
                List<Menu> listChild = getChild(id,activityTypeMenus);
                if (!CollectionUtils.isEmpty(listChild)) {
                    menu.setChildrens(listChild);
                }
            }
        }
        //根据菜单关系对象的id找到对应的根菜单对象
        for (Menu menu : listMenu) {
            if(mr!=null&&menu.getId().equals(mr.getMenuId())){
                business = menu;
            }
            if(fr != null && menu.getId().equals(fr.getMenuId())){
                func = menu;
            }
        }
        //遍历赋值完成后，为每个业务线放入功能菜单子集
        if(business!=null&&func!=null){
            if(business.getChildrens()!=null){
                for (Menu menu1 : business.getChildrens()) {
                    menu1.setChildrens(func.getChildrens());
                }
            }else{
                //初始化的项目存放空数组
                business.setChildrens(new ArrayList<>());
            }
            listMenu.remove(func);
        }else{
            throw new BusinessException(ApiResponseCode.ERROR.getCode(),"请填补数据库功能菜单以及日志查看菜单缺省值");
        }

        HashMap<String, Object> map = new HashMap<>();
        //避免FastJson使用引用$ref解析json对象
        String menuStr = JSONObject.toJSONString(listMenu,SerializerFeature.DisableCircularReferenceDetect);
        map.put("activityTypeMenus", JSONObject.parseArray(menuStr));
        logger.info("菜单列表查询的出参==================【{}】===============", JSON.toJSON(listMenu));
        return map;
    }

    /**
    *@function: 根据菜单名称集合查询所有菜单
    *@param: menuIds
    *@return:
    */
    @Override
    public List<Menu> selectBusinessMenu(List<Integer> menuIds) {
        return menuMapper.selectMenus(menuIds);
    }


    //查询所有的根菜单
    @Override
    public List<Menu> selectRootMenus() {
        return menuMapper.selectRootMenu();
    }


}


